package com.zbkj.crmeb.chant.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.common.PageParamRequest;
import com.crmeb.core.exception.ExceptionCodeEnum;
import com.factory.CommonFactory;
import com.utils.CrmebUtil;
import com.zbkj.crmeb.chant.model.*;
import com.zbkj.crmeb.chant.request.PurchaseProductRequest;
import com.zbkj.crmeb.chant.response.ChannelMerchantPurchaseResponse;
import com.zbkj.crmeb.chant.service.*;
import com.zbkj.crmeb.enums.*;
import com.zbkj.crmeb.order.oprocess.IOrderProcess;
import com.zbkj.crmeb.order.pprocess.AdapayDegreePayOrderProcess;
import com.zbkj.crmeb.order.pprocess.IOrangePayOrderProcess;
import com.zbkj.crmeb.store.dao.StoreProductMerDao;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.request.StoreOrderRefundRequest;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.store.utilService.OrderUtils;
import com.zbkj.crmeb.supplier.dao.SupplierOpenShopDao;
import com.zbkj.crmeb.system.model.SystemAdmin;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
import com.constants.Constants;
import com.crmeb.core.common.CommonResult;
import com.crmeb.core.exception.CrmebException;
import com.crmeb.core.utils.RedisUtil;
import com.crmeb.core.utils.TableNameUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.crmeb.agent.model.Agent;
import com.zbkj.crmeb.agent.service.AgentService;
import com.zbkj.crmeb.category.request.CategoryRequest;
import com.zbkj.crmeb.chant.dao.ChannelMerchantDao;
import com.zbkj.crmeb.chant.dto.ChannelMerchantDTO;
import com.zbkj.crmeb.chant.dto.ChannelMerchantSupplierDTO;
import com.zbkj.crmeb.chant.request.MerchantListRequest;
import com.zbkj.crmeb.chant.vo.ChannelMerchantVO;
import com.zbkj.crmeb.front.service.ProductService;
import com.zbkj.crmeb.member.enums.EquityTypeEnum;
import com.zbkj.crmeb.member.model.ChannelMerchantAttribute;
import com.zbkj.crmeb.member.model.MerchantMemberBenefits;
import com.zbkj.crmeb.member.service.IChannelMerchantAttributeService;
import com.zbkj.crmeb.member.service.IMerchantMemberBenefitsService;
import com.zbkj.crmeb.merchant.api.response.PickIngConfigResponse;
import com.zbkj.crmeb.store.response.SupplierInfo;
import com.zbkj.crmeb.store.vo.StoreOrderInfoVo;
import com.zbkj.crmeb.system.model.SystemConfig;
import com.zbkj.crmeb.system.request.PaymentAccountRequest;
import com.zbkj.crmeb.system.service.SystemAdminService;
import com.zbkj.crmeb.system.service.SystemConfigService;

import cn.hutool.core.convert.Convert;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import javax.management.relation.Role;

/**
 * 渠道商户
 */
@Slf4j
@Service
@Transactional
public class ChannelMerchantImpl extends ServiceImpl<ChannelMerchantDao, ChannelMerchant> implements IChannelMerchantService {
    @Autowired
    private ChannelMerchantDao channelMerchantDao;
    
    @Autowired
    private SupplierOpenShopDao supplierOpenShopDao;
    @Autowired
    private IChannelMerchantAccountService channelMerchantAccountService;
    @Autowired
    private MarkupRateService markupRateService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SystemConfigService systemConfigService;
    @Lazy
    @Autowired
    ProductService productService;
    @Autowired
    private SystemAdminService systemAdminService;
    @Autowired
    StoreProductMerService storeProductMerService;
    @Autowired
    StoreProductService storeProductService;
    @Autowired
    StoreProductValueMerService storeProductValueMerService;
    @Autowired
    AgentService agentService;
    @Autowired
    SupplierService supplierService;
    @Autowired
    private AccountFlowService accountFlowService;
    @Autowired
    private ChannelCategoryConfigService channelCategoryConfigService;
    @Autowired
    private StoreOrderInfoService storeOrderInfoService;
    @Autowired
    private IMerchantMemberBenefitsService merchantMemberBenefitsService;
    @Autowired
    private IChannelMerchantAttributeService channelMerchantAttributeService;
    @Autowired
    private ChannelMerchantRenewalService channelMerchantRenewalService;
    @Resource
    StoreProductMerDao storeProductMerDao;
    @Autowired
    private OrderUtils orderUtils;
    @Autowired
    private Redisson redisson;
    @Value("${productType.merchantId}")
    private Integer productTypeMerchantId;
    @Autowired
    private CommonFactory commonFactory;
    @Autowired
    private ChannelMerchantPurchaseService channelMerchantPurchaseService;
    @Autowired
    private AdapayDegreePayOrderProcess adapayDegreePayOrderProcess;
    @Autowired
    private StoreOrderRefundService storeOrderRefundService;
    @Autowired
    private ReserveMoneyDetailService reserveMoneyDetailService;

    /**
     * 渠道商户列表
     *
     * @return
     */
    @Override
    public PageInfo<ChannelMerchantVO> merchantList(MerchantListRequest request) {
    	// 供应商列表不校验权限
    	if(null == request.getChannelType() || request.getChannelType() != 3) {
    		request.setMerIds(systemAdminService.getAdminMerIds());
    	}
        Page<ChannelMerchant> pageMerchant = PageHelper.startPage(request.getPage(), request.getLimit());
        if(request.getAccountStart() != null && request.getAccountEnd() != null) {
            if (request.getAccountStart().compareTo(request.getAccountEnd()) > 0) {
                throw new CrmebException("最小金额不能大于最大金额！");
            }
        }
        if(request.getCreateTimeStart() != null && request.getCreateTimeEnd() != null) {
            if (request.getCreateTimeStart().compareTo(request.getCreateTimeEnd()) > 0) {
                throw new CrmebException("开始时间不能大于结束时间！");
            }
        }
        // 处理服务商
        List<Integer> agentIds = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(request.getOneLevelAgentIds())) {
            agentIds.addAll(request.getOneLevelAgentIds());
            agentIds.addAll(agentService.listTwoAgentIds(request.getOneLevelAgentIds()));
            // 添加平台商户
            if (IdentityTypeEnum.PLATFORM.getCode().equals(request.getIdentityType())) {
                agentIds.add(0);
            }
        }
        if (CollectionUtils.isNotEmpty(request.getTwoLevelAgentIds())) {
            agentIds.addAll(request.getTwoLevelAgentIds());
            // 添加平台商户
            if (IdentityTypeEnum.PLATFORM.getCode().equals(request.getIdentityType())) {
                agentIds.add(0);
            }
        }
        request.setTwoLevelAgentIds(agentIds);
        List<ChannelMerchantVO> channelMerchantList = channelMerchantDao.merchantList(request);
        if(CollectionUtils.isNotEmpty(channelMerchantList)){
            // 查询商户配置
            List<Integer> idList = channelMerchantList.stream().map(ChannelMerchantVO::getId).collect(Collectors.toList());
            //查询服务商
            List<Integer> agentIdList = channelMerchantList.stream().map(ChannelMerchantVO::getAgentId).collect(Collectors.toList());
            List<Agent> agentList = agentService.list(Wrappers.lambdaQuery(Agent.class).in(Agent::getId, agentIdList));
            Map<Integer, Agent> map = agentList.stream().collect(Collectors.toMap(Agent::getId, e -> e));
            //有效期
            List<ChannelMerchantRenewal> renewalList = channelMerchantRenewalService.list(Wrappers.<ChannelMerchantRenewal>query().select("mer_id ,max(expiration_time) as expirationTime")
                    .lambda().in(ChannelMerchantRenewal::getMerId,idList).groupBy(ChannelMerchantRenewal::getMerId));
            Map<Integer, Date> renewalMap = renewalList.stream().collect(Collectors.toMap(ChannelMerchantRenewal::getMerId, ChannelMerchantRenewal::getExpirationTime));
            Map<Integer, String> indexConfigs = systemConfigService.getMerchantCustomConfigMap(idList, Constants.CONFIG_INDEX);
            Map<Integer, String> productDetailConfigs = systemConfigService.getMerchantCustomConfigMap(idList, Constants.CONFIG_PRODUCT_DETAIL);
            Map<Integer, String> showSupplierConfigs = systemConfigService.getMerchantCustomConfigMap(idList, Constants.CONFIG_KEY_SHOW_SUPPLIER);
            Map<Integer, String> showDiscountConfigs = systemConfigService.getMerchantCustomConfigMap(idList, Constants.CONFIG_KEY_SHOW_DISCOUNT);
            //获取供应商编号
            Map<Integer, String> suppliersNameCodeMap = new HashMap<>();
            Map<Integer, Integer> suppliersTypeMap = new HashMap<>();
            Map<Integer, Supplier> suppliersMap = new HashMap<>();
            if (Objects.isNull(request.getNotChannelType())){
                List<Integer> supplierIds = channelMerchantList.stream().map(i -> i.getSuppliersIds().replace("[", "").replace("]", "")).map(Integer::valueOf).collect(Collectors.toList());
                List<Supplier> suppliers = supplierService.list(Wrappers.<Supplier>lambdaQuery().in(Supplier::getId, supplierIds));
                suppliersNameCodeMap = suppliers.stream().collect(Collectors.toMap(Supplier::getId, e -> null == e.getNameCode() ? "" : e.getNameCode()));
                Map<Integer, Integer> typeMap = suppliers.stream().collect(Collectors.toMap(Supplier::getId, e -> null == e.getSupplierType() ? 0 : e.getSupplierType()));
                suppliersTypeMap.putAll(typeMap);
            } else {
                List<Supplier> suppliers = supplierService.list(Wrappers.<Supplier>lambdaQuery().in(Supplier::getMerId, idList));
                suppliersMap = suppliers.stream().collect(Collectors.toMap(Supplier::getMerId, e -> e));
            }

            Map<Integer, String> finalSuppliersNameCodeMap = suppliersNameCodeMap;
            Map<Integer, Supplier> finalSuppliersMap = suppliersMap;
            channelMerchantList.forEach(e -> {
                e.setIndexConfig(StringUtils.isBlank(indexConfigs.get(e.getId())) ? "1" : indexConfigs.get(e.getId()));
                e.setProductDetailConfig(StringUtils.isBlank(productDetailConfigs.get(e.getId())) ? "0" : productDetailConfigs.get(e.getId()));
                e.setShowSupplier(StringUtils.isBlank(showSupplierConfigs.get(e.getId())) ? 0 : Integer.parseInt(showSupplierConfigs.get(e.getId())));
                e.setShowDiscount(StringUtils.isBlank(showDiscountConfigs.get(e.getId())) ? 1 : Integer.parseInt(showDiscountConfigs.get(e.getId())));
                if(e.getAgentId() == 0){
                    e.setAgentLevel(0);
                }else {
                    Agent agent = map.get(e.getAgentId());
                    e.setAgentName(agent.getAgentName());
                    e.setAgentLevel(agent.getParentId() == 0 ? 1 : 2);
                }
                e.setExpirationTime(renewalMap.get(e.getId()));
                if (Objects.isNull(request.getNotChannelType())){
                    e.setSuppliersNameCode(finalSuppliersNameCodeMap.get(Integer.valueOf(e.getSuppliersIds().replace("[", "").replace("]", ""))));
                    e.setSuppliersType(suppliersTypeMap.get(Integer.valueOf(e.getSuppliersIds().replace("[", "").replace("]", ""))));
                    if(e.getSuppliersType() != null){
                        e.setSuppliersTypeName(SupplierTypeEnum.getTypeByCode(e.getSuppliersType()).getTypeName());
                    }
                    Supplier  supplier =  supplierService.getById(Integer.valueOf(e.getSuppliersIds().replace("[", "").replace("]", "")));
                    if(Objects.nonNull(supplier)){
                        e.setDirectMailType(supplier.getDirectMailType());
                    }else
                    {
                        e.setDirectMailType(0);
                    }

                } else {
                    e.setIsEurope(Objects.isNull(finalSuppliersMap.get(e.getId())) ? 0 : 1);
                    e.setPayType(orderUtils.getOrderPayType(e.getId()).getCode());
                }
            });
        }
        return CommonPage.copyPageInfo(pageMerchant, channelMerchantList);
    }

    /**
     * 渠道商户列表
     *
     * @return
     */
    @Override
    public PageInfo<ChannelMerchantVO> merchantListV2(MerchantListRequest request, boolean onlyWokg) {
    	// 供应商列表不校验权限
//    	if(null == request.getChannelType() || request.getChannelType() != 3) {
//    		request.setMerIds(systemAdminService.getAdminMerIds());
//    	}
        Page<ChannelMerchant> pageMerchant = PageHelper.startPage(request.getPage(), request.getLimit());
        if(request.getAccountStart() != null && request.getAccountEnd() != null) {
            if (request.getAccountStart().compareTo(request.getAccountEnd()) > 0) {
                throw new CrmebException("最小金额不能大于最大金额！");
            }
        }
        if(request.getCreateTimeStart() != null && request.getCreateTimeEnd() != null) {
            if (request.getCreateTimeStart().compareTo(request.getCreateTimeEnd()) > 0) {
                throw new CrmebException("开始时间不能大于结束时间！");
            }
        }
        // 处理服务商
        List<Integer> agentIds = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(request.getOneLevelAgentIds())) {
            agentIds.addAll(request.getOneLevelAgentIds());
            agentIds.addAll(agentService.listTwoAgentIds(request.getOneLevelAgentIds()));
            // 添加平台商户
            if (IdentityTypeEnum.PLATFORM.getCode().equals(request.getIdentityType())) {
                agentIds.add(0);
            }
        }
        if (CollectionUtils.isNotEmpty(request.getTwoLevelAgentIds())) {
            agentIds.addAll(request.getTwoLevelAgentIds());
            // 添加平台商户
            if (IdentityTypeEnum.PLATFORM.getCode().equals(request.getIdentityType())) {
                agentIds.add(0);
            }
        }
        request.setTwoLevelAgentIds(agentIds);
        List<ChannelMerchantVO> channelMerchantList = channelMerchantDao.merchantList(request);
        if(CollectionUtils.isNotEmpty(channelMerchantList)){
            // 查询商户配置
            List<Integer> idList = channelMerchantList.stream().map(ChannelMerchantVO::getId).collect(Collectors.toList());
            //查询服务商
            List<Integer> agentIdList = channelMerchantList.stream().map(ChannelMerchantVO::getAgentId).collect(Collectors.toList());
            List<Agent> agentList = agentService.list(Wrappers.lambdaQuery(Agent.class).in(Agent::getId, agentIdList));
            Map<Integer, Agent> map = agentList.stream().collect(Collectors.toMap(Agent::getId, e -> e));
            //有效期
            List<ChannelMerchantRenewal> renewalList = channelMerchantRenewalService.list(Wrappers.<ChannelMerchantRenewal>query().select("mer_id ,max(expiration_time) as expirationTime")
                    .lambda().in(ChannelMerchantRenewal::getMerId,idList).groupBy(ChannelMerchantRenewal::getMerId));
            Map<Integer, Date> renewalMap = renewalList.stream().collect(Collectors.toMap(ChannelMerchantRenewal::getMerId, ChannelMerchantRenewal::getExpirationTime));
            Map<Integer, String> indexConfigs = systemConfigService.getMerchantCustomConfigMap(idList, Constants.CONFIG_INDEX);
            Map<Integer, String> productDetailConfigs = systemConfigService.getMerchantCustomConfigMap(idList, Constants.CONFIG_PRODUCT_DETAIL);
            Map<Integer, String> showSupplierConfigs = systemConfigService.getMerchantCustomConfigMap(idList, Constants.CONFIG_KEY_SHOW_SUPPLIER);
            Map<Integer, String> showDiscountConfigs = systemConfigService.getMerchantCustomConfigMap(idList, Constants.CONFIG_KEY_SHOW_DISCOUNT);
            //获取供应商编号
            Map<Integer, String> suppliersNameCodeMap = new HashMap<>();
            Map<Integer, Integer> suppliersTypeMap = new HashMap<>();
            Map<Integer, Supplier> suppliersMap = new HashMap<>();
            if (Objects.isNull(request.getNotChannelType())){
                List<Integer> supplierIds = channelMerchantList.stream().map(i -> i.getSuppliersIds().replace("[", "").replace("]", "")).map(Integer::valueOf).collect(Collectors.toList());
                List<Supplier> suppliers = supplierService.list(Wrappers.<Supplier>lambdaQuery().in(Supplier::getId, supplierIds));
                suppliersNameCodeMap = suppliers.stream().collect(Collectors.toMap(Supplier::getId, e -> null == e.getNameCode() ? "" : e.getNameCode()));
                Map<Integer, Integer> typeMap = suppliers.stream().collect(Collectors.toMap(Supplier::getId, e -> null == e.getSupplierType() ? 0 : e.getSupplierType()));
                suppliersTypeMap.putAll(typeMap);
            } else {
                List<Supplier> suppliers = supplierService.list(Wrappers.<Supplier>lambdaQuery().in(Supplier::getMerId, idList));
                suppliersMap = suppliers.stream().collect(Collectors.toMap(Supplier::getMerId, e -> e));
            }

            Map<Integer, String> finalSuppliersNameCodeMap = suppliersNameCodeMap;
            Map<Integer, Supplier> finalSuppliersMap = suppliersMap;
            channelMerchantList.forEach(e -> {
                e.setIndexConfig(StringUtils.isBlank(indexConfigs.get(e.getId())) ? "1" : indexConfigs.get(e.getId()));
                e.setProductDetailConfig(StringUtils.isBlank(productDetailConfigs.get(e.getId())) ? "0" : productDetailConfigs.get(e.getId()));
                e.setShowSupplier(StringUtils.isBlank(showSupplierConfigs.get(e.getId())) ? 0 : Integer.parseInt(showSupplierConfigs.get(e.getId())));
                e.setShowDiscount(StringUtils.isBlank(showDiscountConfigs.get(e.getId())) ? 1 : Integer.parseInt(showDiscountConfigs.get(e.getId())));
                if(e.getAgentId() == 0){
                    e.setAgentLevel(0);
                }else {
                    Agent agent = map.get(e.getAgentId());
                    e.setAgentName(agent.getAgentName());
                    e.setAgentLevel(agent.getParentId() == 0 ? 1 : 2);
                }
                e.setExpirationTime(renewalMap.get(e.getId()));
                if (Objects.isNull(request.getNotChannelType())){
                    e.setSuppliersNameCode(finalSuppliersNameCodeMap.get(Integer.valueOf(e.getSuppliersIds().replace("[", "").replace("]", ""))));
                    e.setSuppliersType(suppliersTypeMap.get(Integer.valueOf(e.getSuppliersIds().replace("[", "").replace("]", ""))));

                    Supplier  supplier =  supplierService.getById(Integer.valueOf(e.getSuppliersIds().replace("[", "").replace("]", "")));
                    if(Objects.nonNull(supplier)){
                        e.setDirectMailType(supplier.getDirectMailType());
                    }else
                    {
                        e.setDirectMailType(0);
                    }

                } else {
                    e.setIsEurope(Objects.isNull(finalSuppliersMap.get(e.getId())) ? 0 : 1);
                    e.setPayType(orderUtils.getOrderPayType(e.getId()).getCode());
                }
            });
        }
        // TODO 暂时只展示 我爱跨购 平台
        if (onlyWokg) {
            List<ChannelMerchantVO> list = channelMerchantList.stream().filter(e -> Objects.equals(e.getChannelName(), "我爱跨购")).collect(Collectors.toList());
            return CommonPage.copyPageInfo(pageMerchant, list);
        }else {
            return CommonPage.copyPageInfo(pageMerchant, channelMerchantList);
        }

    }

    /**
     * 删除渠道商户
     *
     * @param id
     * @return
     */
    @Override
    public boolean deleteMerchant(Integer id) {
        LambdaUpdateWrapper<ChannelMerchant> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(ChannelMerchant::getId, id);
        lambdaUpdateWrapper.set(ChannelMerchant::getIsDel, true);
        if(this.update(lambdaUpdateWrapper)){
            redisUtil.remove(Constants.CHANNEL_MERCHANT + id);
            return true;
        }else {
            return false;
        }
    }

    /**
     * 添加渠道商户
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<String> addMerchant(ChannelMerchantDTO entity) {
        validatedAgent(entity);
        ChannelMerchant channelMerchant = new ChannelMerchant();
        ChannelMerchantAccount channelMerchantAccount = new ChannelMerchantAccount();
        BeanUtils.copyProperties(entity, channelMerchant);
        BeanUtils.copyProperties(entity, channelMerchantAccount);
        
        if(save(channelMerchant)){
            Integer shopId = entity.getShopId();
            supplierOpenShopDao.updateShopMerIdById(channelMerchant.getId(), shopId);
            // 商户账户
            channelMerchantAccount.setMerId(channelMerchant.getId());
            channelMerchantAccountService.save(channelMerchantAccount);
            // 费率配置
            MarkupRate markupRate = new MarkupRate();
            markupRate.setType(MarkupRateTypeEnum.PLAT_平台加价率.getType());
            markupRate.setRatio(channelMerchant.getMarkupRate());
            markupRate.setMerId(channelMerchant.getId());
            markupRateService.save(markupRate);
            // 商户自定义配置（首页|多供应商|是否显示折扣）
            systemConfigService.addMerchantCustomConfig(channelMerchant.getId(), entity);
            // 创建商户协议
        	ChannelMerchantAttribute channelMerchantAttribute = channelMerchantAttributeService.getOne(Wrappers.<ChannelMerchantAttribute>lambdaQuery()
            		// .eq(ChannelMerchantAttribute::getMerId, channelMerchant.getId())
            		.last("LIMIT 1")
            		);
            /*if (Objects.isNull(channelMerchantAttribute)){
                channelMerchantAttribute = new ChannelMerchantAttribute();
            }*/
        	channelMerchantAttribute.setId(null);
        	channelMerchantAttribute.setMerId(channelMerchant.getId());
            channelMerchantAttribute.setCreateTime(LocalDateTime.now());
            channelMerchantAttribute.setUpdateTime(null);
        	channelMerchantAttributeService.save(channelMerchantAttribute);
            
            //创建商户商品表, sku表
            String tableName = TableNameUtil.getProductMerName(channelMerchant.getId());
            storeProductMerService.createTable(tableName);
            storeProductValueMerService.createTable(TableNameUtil.getProductValueMerName(channelMerchant.getId()));

            // 自动下架权限内商品(异步)
            if(0 == channelMerchant.getAutomaticShelves()) {
    			log.info("--------------- 异步同步商户商品权限: {} ---------------", channelMerchant.getId());
                productService.autoDownProductTask(channelMerchant.getId());
            }
            redisUtil.set(Constants.CHANNEL_MERCHANT + channelMerchant.getId(),channelMerchant,24L,TimeUnit.HOURS);

            //设置渠道商户订单超时未支付撤销时间
            SystemConfig systemConfig = new SystemConfig(Constants.CONFIG_KEY_ORDER_CANCEL_TIME + "_" + channelMerchant.getId()
                    ,Constants.CONFIG_KEY_ORDER_CANCEL_TIME + "_" + channelMerchant.getId()
                    ,100
                    ,"120"
                    ,false);
            systemConfigService.save(systemConfig);
            //给当前创建商户的用户赋予权限(2023.07.17)
            if (Boolean.FALSE.equals(entity.getIsRegister())) {
                addMerId(channelMerchant.getId());
            }
            // 是否允许自建
            if (entity.getIsEurope() == 1){
                saveSupplier(channelMerchant);
            }
            // 产品类型变更时，更新主账号角色
            updateAccountRole(entity.getProductType(), "["+ channelMerchant.getId() +"]");
            return CommonResult.success(String.valueOf(channelMerchant.getId()), ExceptionCodeEnum.SUCCESS.getMessage());
        }else{
            return CommonResult.failed();
        }
    }

    /**
     * 添加渠道商户
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
	public CommonResult<String> addMerchantSupplier(ChannelMerchantSupplierDTO entity) {
    	// 校验是否已经存在绑定的供应商
    	int channelMerchantCount = this.count(Wrappers.<ChannelMerchant>lambdaQuery()
    			.eq(ChannelMerchant :: getChannelType, 3)
    			.eq(ChannelMerchant :: getSuppliersIds, Arrays.asList(entity.getChannelSupplierId()).toString())
    			);
    	if(0 < channelMerchantCount) {
            throw new CrmebException("该供应商已存在!");
    	}
    	
    	// 供应商类型自动上架
    	entity.setAutomaticShelves(1);
    	entity.setChannelType(3);
    	// 处理供应商关联关系
    	Supplier supplier = supplierService.getById(entity.getChannelSupplierId());
    	entity.setChannelName(supplier.getSuppliersName());
    	entity.setSuppliersIds(Arrays.asList(entity.getChannelSupplierId()).toString());
    	entity.setBrandIds(Arrays.asList().toString());
    	entity.setTempId(StockAreaTempEnum.listValue().toString());

		ChannelMerchant channelMerchant = new ChannelMerchant();
		ChannelMerchantAccount channelMerchantAccount = new ChannelMerchantAccount();
		BeanUtils.copyProperties(entity, channelMerchant);
		BeanUtils.copyProperties(entity, channelMerchantAccount);

		if (save(channelMerchant)) {
			// 商户账户
			channelMerchantAccount.setMerId(channelMerchant.getId());
			channelMerchantAccountService.save(channelMerchantAccount);
			// 费率配置
			MarkupRate markupRate = new MarkupRate();
			markupRate.setType(MarkupRateTypeEnum.PLAT_平台加价率.getType());
			markupRate.setRatio(channelMerchant.getMarkupRate());
			markupRate.setMerId(channelMerchant.getId());
			markupRateService.save(markupRate);
			// 创建商户商品表、sku表
			storeProductMerService.createTable(TableNameUtil.getProductMerName(channelMerchant.getId()));
			storeProductValueMerService.createTable(TableNameUtil.getProductValueMerName(channelMerchant.getId()));

            //添加供应商编号
            supplier.setNameCode(entity.getChannelNameCode());
            supplier.setSupplierType(entity.getSupplierType());
            supplierService.updateById(supplier);

			return CommonResult.success();
		} else {
			return CommonResult.failed();
		}
	}
    
    /**
     * 修改供应商
     * @param entity
     * @return
     */
    @Override
    public CommonResult<String> updateMerchantSupplier(ChannelMerchantSupplierDTO entity) {
    	// 校验是否已经存在绑定的供应商
    	int channelMerchantCount = this.count(Wrappers.<ChannelMerchant>lambdaQuery()
    			.ne(ChannelMerchant :: getId, entity.getId())
    			.eq(ChannelMerchant :: getChannelType, 3)
    			.eq(ChannelMerchant :: getSuppliersIds, Arrays.asList(entity.getChannelSupplierId()).toString())
    			);
    	if(0 < channelMerchantCount) {
            throw new CrmebException("该供应商已存在!");
    	}
    	
    	// 供应商类型自动上架
    	entity.setAutomaticShelves(1);
    	entity.setChannelType(3);
    	// 处理供应商关联关系
    	Supplier supplier = supplierService.getById(entity.getChannelSupplierId());
    	entity.setChannelName(supplier.getSuppliersName());
    	entity.setSuppliersIds(Arrays.asList(entity.getChannelSupplierId()).toString());
    	entity.setBrandIds(Arrays.asList().toString());
    	entity.setTempId(StockAreaTempEnum.listValue().toString());
    	
    	ChannelMerchant channelMerchant = new ChannelMerchant();
    	ChannelMerchantAccount channelMerchantAccount = new ChannelMerchantAccount();
    	BeanUtils.copyProperties(entity, channelMerchant);
    	BeanUtils.copyProperties(entity, channelMerchantAccount);
        //保存供应商编码
        supplier.setNameCode(entity.getChannelNameCode());
        supplier.setSupplierType(entity.getSupplierType());

    	if(updateById(channelMerchant) && supplierService.updateById(supplier)){
            redisUtil.set(Constants.CHANNEL_MERCHANT + channelMerchant.getId(),channelMerchant,24L,TimeUnit.HOURS);
    		return CommonResult.success();
    	}else{
    		return CommonResult.failed();
    	}
    }

    public void validatedAgent(ChannelMerchantDTO entity) {
        if(entity.getAgentType() == 0 && entity.getAgentId() != 0){
            throw new CrmebException("服务商类型或id异常");
        }
        if(entity.getAgentType() != 0){
            Agent agent = agentService.getById(entity.getAgentId());
            if(Objects.isNull(agent) || agent.getIsDel() == 1){
                throw new CrmebException("该服务商不存在");
            }
            if(entity.getAgentType() == 1 && agent.getParentId() != 0){
                throw new CrmebException("该服务商不是一级服务商");
            }
            if(entity.getAgentType() == 2 && agent.getParentId() == 0){
                throw new CrmebException("该服务商不是二级服务商");
            }
            if(dataAccess(agent.getBrandIds(), entity.getBrandIds())){
                throw new CrmebException("可见品牌不能超过服务商权限");
            }
            if(dataAccess(agent.getSuppliersIds(), entity.getSuppliersIds())){
                throw new CrmebException("可见供应商不能超过服务商权限");
            }
            if(dataAccess(agent.getTempId(), entity.getTempId())){
                throw new CrmebException("发货地不能超过服务商权限");
            }
        }
    }

    public boolean dataAccess(String source, String target) {
        List<Integer> agentList = JSONArray.parseArray(source, Integer.class);
        List<Integer> list = JSONArray.parseArray(target, Integer.class);
        if(CollectionUtils.isNotEmpty(agentList) && CollectionUtils.isEmpty(list) ){
            return true;
        }
        if(CollectionUtils.isNotEmpty(agentList) && CollectionUtils.isNotEmpty(list)){
            return !agentList.containsAll(list);
        }
        return false;
    }

    /**
     * 修改渠道商户
     * @param entity
     * @return
     */
    @Override
    public CommonResult<String> updateMerchant(ChannelMerchantDTO entity) {
        validatedAgent(entity);
        ChannelMerchant channelMerchant = new ChannelMerchant();
        ChannelMerchantAccount channelMerchantAccount = new ChannelMerchantAccount();
        BeanUtils.copyProperties(entity, channelMerchant);
        BeanUtils.copyProperties(entity, channelMerchantAccount);

        // 更新商户商品动态表数据
        productService.batchRenewalMerTask(entity, channelMerchant);

        if(updateById(channelMerchant)){
            // 商户账户
            channelMerchantAccount.setMerId(channelMerchant.getId());
            channelMerchantAccountService.update(Wrappers.<ChannelMerchantAccount>lambdaUpdate()
                    .eq(ChannelMerchantAccount :: getMerId, channelMerchant.getId())
                    .set(!Objects.isNull(channelMerchantAccount.getStatus()),ChannelMerchantAccount::getStatus, channelMerchantAccount.getStatus())
                    .set(ChannelMerchantAccount :: getAccountType, channelMerchantAccount.getAccountType())
                    .set(ChannelMerchantAccount :: getWarnMoney, channelMerchantAccount.getWarnMoney())
                    .set(ChannelMerchantAccount :: getBankName, channelMerchantAccount.getBankName())
                    .set(ChannelMerchantAccount :: getBankNo, channelMerchantAccount.getBankNo())
                    .set(ChannelMerchantAccount :: getCreateBank, channelMerchantAccount.getCreateBank())
                    .set(ChannelMerchantAccount :: getUpdateTime, new Date())
                    );
            
            if(!Objects.isNull(channelMerchant.getMarkupRate())){
                // 品牌对应
                MarkupRate markupRate = markupRateService.getOne(Wrappers.<MarkupRate>lambdaQuery()
                        .eq(MarkupRate::getMerId, channelMerchant.getId())
                        .eq(MarkupRate ::getType, MarkupRateTypeEnum.PLAT_平台加价率.getType())
                        .last("LIMIT 1")
                );
                if(null == markupRate){
                    markupRate = new MarkupRate();
                }
                markupRate.setMerId(channelMerchant.getId());
                markupRate.setType(MarkupRateTypeEnum.PLAT_平台加价率.getType());
                markupRate.setRatio(entity.getMarkupRate());
                markupRateService.saveOrUpdate(markupRate);
                redisUtil.remove(Constants.PLAT_RATIO+channelMerchant.getId());
            }

            // 更新折扣配置
            systemConfigService.updateMerchantCustomConfig(channelMerchant.getId(), entity);

            // 自动下架权限内商品(异步)
			if(0 == channelMerchant.getAutomaticShelves()) {
				productService.autoUpOrDownProductTask(channelMerchant.getId(), true);
                productService.autoDownProductTask(channelMerchant.getId());
			} else if(1 == channelMerchant.getAutomaticShelves()) {
				productService.autoUpOrDownProductTask(channelMerchant.getId(), false);
			}
            //删除商品活跃表无权限商品记录(异步)
            productService.removeDownProduct(channelMerchant);

            redisUtil.set(Constants.CHANNEL_MERCHANT + channelMerchant.getId(),channelMerchant,24L,TimeUnit.HOURS);
            if (entity.getIsEurope() == 1){
                Supplier one = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getMerId, channelMerchant.getId()).last("limit 1"));
                if (Objects.isNull(one)){
                    saveSupplier(channelMerchant);
                }
            }
            // 更新主账号角色
            updateAccountRole(entity.getProductType(), "[" + channelMerchant.getId() + "]");
            return CommonResult.success();
        }else{
            return CommonResult.failed();
        }
    }

    /**
     * 获取平台收款账户
     * @return
     */
    @Override
    public PaymentAccountRequest PaymentAccount() {
        //收款账户
        SystemConfig accountForm = Optional.ofNullable(systemConfigService.getOne(Wrappers.<SystemConfig>lambdaQuery().eq(SystemConfig::getName, Constants.ACCOUNT_FORM).last("LIMIT 1"))).orElse(new SystemConfig());
        //收款账号
        SystemConfig accountNumber = Optional.ofNullable(systemConfigService.getOne(Wrappers.<SystemConfig>lambdaQuery().eq(SystemConfig::getName, Constants.ACCOUNT_NUMBER).last("LIMIT 1"))).orElse(new SystemConfig());
        //开户行
        SystemConfig openingBank = Optional.ofNullable(systemConfigService.getOne(Wrappers.<SystemConfig>lambdaQuery().eq(SystemConfig::getName, Constants.OPENING_BANK).last("LIMIT 1"))).orElse(new SystemConfig());
        //客服二维码
        SystemConfig customerServiceQRCode = Optional.ofNullable(systemConfigService.getOne(Wrappers.<SystemConfig>lambdaQuery().eq(SystemConfig::getName, Constants.CUSTOMER_SERVICE_QR_CODE).last("LIMIT 1"))).orElse(new SystemConfig());
        PaymentAccountRequest paymentAccountRequest = new PaymentAccountRequest();
        paymentAccountRequest.setAccountForm(accountForm.getValue())
                .setAccountNumber(accountNumber.getValue())
                .setOpeningBank(openingBank.getValue())
                .setCustomerServiceQRCode(customerServiceQRCode.getValue());
        return paymentAccountRequest;
    }

    /**
     * 根据id获得渠道商户信息
     * @param id
     * @return
     */
    @Override
    public ChannelMerchantVO getMerchantById(Integer id) {
        ChannelMerchantVO channelMerchantVO = channelMerchantDao.getMerchantById(id);
        SystemConfig merchantCustomConfig = systemConfigService.getMerchantCustomConfig(id, Constants.CONFIG_KEY_SHOW_DISCOUNT);
        channelMerchantVO.setShowDiscount(Integer.parseInt(merchantCustomConfig.getValue()));
        return channelMerchantVO;
    }

    /**
     * 获取商户发货地
     * @param merId
     * @return
     */
    @Override
    public List<StockAreaTempEnum> getStockArea(Integer merId) {
        ChannelMerchant channelMerchant = Optional.ofNullable(getById(merId)).orElse(new ChannelMerchant());
        JSONArray tempJson = JSONArray.parseArray(channelMerchant.getTempId());
        List<StockAreaTempEnum> stockAreaTempEnumList = null;
        if(!tempJson.isEmpty()){
            List<Integer> tempList = tempJson.toJavaList(Integer.class);
            stockAreaTempEnumList = tempList.stream().map(StockAreaTempEnum::valueOf).collect(Collectors.toList());
        }
        return stockAreaTempEnumList;
    }

    @Override
    public SupplierInfo getSupplierInfo(Integer merId) {
        ChannelMerchant channelMerchant = this.getById(merId);
        if(channelMerchant.getChannelType() != 3){
            throw new CrmebException("渠道类型异常");
        }
        List<Integer> suppliersIdList = JSON.parseArray(channelMerchant.getSuppliersIds(), Integer.class);
        if(suppliersIdList == null || suppliersIdList.size() != 1){
            throw new CrmebException("绑定供应商异常");
        }
        Supplier supplier = supplierService.getById(suppliersIdList.get(0));
        if(StringUtils.isBlank(supplier.getBarcode())){
            throw new CrmebException("供应商未绑定barcode");
        }
        if(Objects.isNull(supplier.getIsEurope())){
            throw new CrmebException("供应商未绑定is_europe");
        }
        if(Objects.isNull(supplier.getMerchantId())){
            throw new CrmebException("供应商未绑定merchant_id");
        }
        SupplierInfo supplierInfo = new SupplierInfo();
        if(StringUtils.isNotBlank(channelMerchant.getCurrency())){
            supplierInfo.setCurrency(CurrencyEnum.valueOf(channelMerchant.getCurrency()));
        }
        supplierInfo.setSupplierId(supplier.getId());
        supplierInfo.setSupplierName(supplier.getSuppliersName());
        supplierInfo.setCreateTime(channelMerchant.getCreateTime());
        supplierInfo.setBarcode(supplier.getBarcode());
        supplierInfo.setIsEurope(supplier.getIsEurope());
        supplierInfo.setMerchantId(supplier.getMerchantId());
        if(Objects.nonNull(channelMerchant.getApplyId())){
            supplierInfo.setApplyId(channelMerchant.getApplyId());
        }
        return supplierInfo;
    }

    @Override
    public void purchaseSupplierGood(PurchaseGoods goods, StoreOrderInfoVo orderInfo) {
        Supplier supplier = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getIsEurope, goods.getChannelType()));
        if(supplier != null){
            //订单设置实际供应商（查询使用）
            storeOrderInfoService.update(Wrappers.<StoreOrderInfo>lambdaUpdate().set(StoreOrderInfo::getActualSupplierId,supplier.getId())
                    .eq(StoreOrderInfo::getId,orderInfo.getId()));
            LambdaQueryWrapper<ChannelMerchant> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(ChannelMerchant::getChannelType,3);
            lambdaQueryWrapper.eq(ChannelMerchant::getSuppliersIds,"["+supplier.getId()+"]");
            ChannelMerchant channelMerchant = this.getOne(lambdaQueryWrapper);
            if(channelMerchant != null){
                ChannelMerchantAccount merchant = new ChannelMerchantAccount();
                BigDecimal price = goods.getGoodsPrice();
                if(StringUtils.isNotBlank(channelMerchant.getCurrency()) && !channelMerchant.getCurrency().equals(CurrencyEnum.CN.toString())){
                    price = price.divide(goods.getExchangeRate(), 2, RoundingMode.UP);
                }
                merchant.setMerId(channelMerchant.getId());
                merchant.setAccount(price);
                merchant.setTotalMoney(price);
                channelMerchantAccountService.calcMoney(merchant);
                accountFlowService.saveAccountFlow(channelMerchant.getId(),goods.getId(),orderInfo.getInfo().getProductInfo().getUserId(),goods.getIp(),
                        AccountFlowTypeEnum.PRODUCT,price,null,null, "购买商品");
            }
        }
    }

    @Override
    public ChannelMerchant getChannelMerchantByMerId(Integer merId) {
        ChannelMerchant channelMerchant = (ChannelMerchant) redisUtil.get(Constants.CHANNEL_MERCHANT + merId);
        if (Objects.isNull(channelMerchant)){
            channelMerchant = channelMerchantDao.selectById(merId);
            redisUtil.set(Constants.CHANNEL_MERCHANT + merId,channelMerchant,24L, TimeUnit.HOURS);
        }
        return channelMerchant;
    }

    /**
     * 编辑渠道商户分类
     * @param categoryRequest
     * @return java.lang.Boolean
     */
    @Override
    public Boolean updCategoryByChannel(CategoryRequest categoryRequest) {
        return channelCategoryConfigService.updCategoryEnableFlag(categoryRequest);
    }

    @Override
    public ChannelMerchantVO getMerchantConfigDetail(Integer merId) {
        ChannelMerchantVO channelMerchantVO = new ChannelMerchantVO();
        channelMerchantVO.setId(merId);

        SystemConfig showSupplierConfig = systemConfigService.getMerchantCustomConfig(merId, Constants.CONFIG_KEY_SHOW_SUPPLIER);
        SystemConfig pushPddConfig = systemConfigService.getMerchantCustomConfig(merId, Constants.CONFIG_KEY_PUSH_PDD);
        channelMerchantVO.setShowSupplier(Objects.isNull(showSupplierConfig) ? 0 : Integer.parseInt(showSupplierConfig.getValue()));
        channelMerchantVO.setPushPdd(Objects.isNull(pushPddConfig) ? 0 : Integer.parseInt(showSupplierConfig.getValue()));
        //查询商户是否开启会员指定商品折扣
        MerchantMemberBenefits merchantMemberBenefits = merchantMemberBenefitsService.getOne(Wrappers.lambdaQuery(MerchantMemberBenefits.class)
                .eq(MerchantMemberBenefits::getMerId,merId)
                .eq(MerchantMemberBenefits::getEquityEnableFlag,true)
                .eq(MerchantMemberBenefits::getEquityType, EquityTypeEnum.DISCOUNT.getCode())
                .eq(MerchantMemberBenefits::getDiscountConditions,2));
        channelMerchantVO.setShowMemberDiscount(Objects.nonNull(merchantMemberBenefits));
        //查询是否开启自建转云仓
        Supplier supplier = supplierService.getOne(Wrappers.lambdaQuery(Supplier.class).eq(Supplier::getMerId, merId));
        channelMerchantVO.setShowSelfBuilt(Objects.nonNull(supplier) && Objects.nonNull(supplier.getIsEurope()));
        ChannelMerchant merchant = this.getChannelMerchantByMerId(merId);
        channelMerchantVO.setBatchPicking(Objects.isNull(merchant.getBatchPicking()) ? 0 : merchant.getBatchPicking());
        return channelMerchantVO;
    }

    @Override
    public ChannelMerchant getMerchantByRelated(Integer channelType,String suppliersIds) {
        List<ChannelMerchant> channelMerchantList = Convert.toList(ChannelMerchant.class, redisUtil.getList(Constants.CHANNEL_MERCHANT + "*"));
        ChannelMerchant channelMerchant = channelMerchantList.stream().filter(channelMerchant1 -> Objects.equals(channelMerchant1.getChannelType(), channelType)
                && Objects.equals(channelMerchant1.getSuppliersIds(),suppliersIds)).findFirst().orElse(null);
        return channelMerchant;
    }

    @Override
    public PickIngConfigResponse getPickingConfig(Integer merId) {
        PickIngConfigResponse response = new PickIngConfigResponse();
        ChannelMerchant channelMerchant = this.getChannelMerchantByMerId(merId);
        ChannelMerchantAttribute merchantAttribute = Optional.ofNullable(channelMerchantAttributeService.getOne(Wrappers.<ChannelMerchantAttribute>lambdaQuery().eq(ChannelMerchantAttribute::getMerId, merId).last("LIMIT 1"))).orElse(new ChannelMerchantAttribute());
        response.setBatchPicking(channelMerchant.getBatchPicking() == null ? 0 : channelMerchant.getBatchPicking());
        response.setIsPicking(merchantAttribute.getIsPicking() == null ? 0 : merchantAttribute.getIsPicking());
        return response;
    }

    /**
     * 功能描述: 添加商户/修改商户允许自建时，供应商表添加对应信息
     * @Param: [channelMerchant]
     * @Return: void
     * @Author: wangzh
     * @Date: 2022/12/20 10:36
     */
    private void saveSupplier(ChannelMerchant channelMerchant){
        if (channelMerchant.getChannelType() == 3 || channelMerchant.getChannelType() == 9){
            return;
        }
        Integer merId = channelMerchant.getId();
        String barcode = "10";
        String merchantId = "100";
        if (String.valueOf(merId).length() == 1){
            barcode = "100";
            merchantId = "1000";
        }
        Supplier supplier = new Supplier();
        supplier.setSuppliersName(channelMerchant.getChannelName())
                .setStockArea(StockAreaTempEnum.CN.getStockAreaCode())
                .setBarcode(barcode + merId)
                .setMerchantId(Integer.valueOf(merchantId + merId))
                .setMerId(merId);
        supplierService.save(supplier);
    }

    /**
     * 功能描述: 商户产品类型变更时，更新主账号角色
     * @Param: [roleCode, merId]
     * @Return: void
     * @Author: wangzh
     * @Date: 2023/4/25 14:40
     */
    public void updateAccountRole(Integer roleCode, String merId) {
        if (Objects.nonNull(roleCode)) {
            SystemAdmin one = systemAdminService.getOne(Wrappers.<SystemAdmin>lambdaQuery()
                    .eq(SystemAdmin::getMerId, merId)
                    .eq(SystemAdmin::getIdentityType, 2)
                    .orderByAsc(SystemAdmin::getId)
                    .last("limit 1"));
            if (Objects.nonNull(one)) {
                one.setRoles(RoleEnum.getEnumByCode(roleCode).getRole());
                systemAdminService.updateById(one);
            }
        }
    }

    /**
     * 功能描述: 操作的管理员添加商户id
     * @Param: [merId]
     * @Return: void
     * @Author: wangzh
     * @Date: 2023/4/26 14:10
     */
    public void addMerId(Integer merId) {
        SystemAdmin adminInfo = systemAdminService.getInfo();
        JSONArray merIds = JSONArray.parseArray(adminInfo.getMerId());
        if (!merIds.contains(merId)) {
            merIds.add(merId);
        }
        adminInfo.setMerId(merIds.toString());
        systemAdminService.updateById(adminInfo);
    }

    @Override
    public Boolean merAddRemarks(String remarks, Integer merId) {
        return this.update(Wrappers.<ChannelMerchant>lambdaUpdate()
                .eq(ChannelMerchant::getId, merId)
                .set(ChannelMerchant::getRemarks, remarks));
    }

    @Override
    public Map<String, Object> purchaseProduct(PurchaseProductRequest purchaseProductRequest, String ip) {
        // 检查是否为体验版
        // 是：直接返回，前端展示商务二维码
        ChannelMerchant channelMerchant = this.getChannelMerchantByMerId(purchaseProductRequest.getMerId());
        if (Objects.isNull(channelMerchant.getProductType()) || channelMerchant.getProductType().equals(1)) {
            Map<String, Object> map = new HashMap<>();
            map.put("message", "请联系客户经理");
            return map;
        // 否：进行支付流程
        } else if (channelMerchant.getProductType() > purchaseProductRequest.getProductType()) {
            throw new CrmebException("不支持向下购买，请联系客户经理");
        } else {
            String lockKey = "mer_id" + purchaseProductRequest.getMerId();
            RLock lock = redisson.getLock(lockKey);
            try {
                if (!lock.tryLock()) {
                    throw new CrmebException("该商户正在购买服务！");
                }
                log.info("商户购买产品与服务：{}", RoleEnum.getEnumByCode(purchaseProductRequest.getProductType()).getMsg());
                // 订单id
                String orderNo = CrmebUtil.getOrderNo(Constants.PAY_TYPE_WE_CHAT);
                purchaseProductRequest.setOrderNo(orderNo);
                createPurchaseOrder(orderNo, purchaseProductRequest.getProductType(), purchaseProductRequest.getMerId());
                // 获取支付渠道
                Integer payType = orderUtils.getOrderPayType(productTypeMerchantId).getCode();
                IOrderProcess payOrderProcess = commonFactory.getOrderType(payType);

                return payOrderProcess.purchaseProduct(purchaseProductRequest, ip);
            } finally {
                if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }
        }
    }

    @Override
    public Boolean refund(BigDecimal amount, String orderId) {
        StoreOrderRefundRequest request = new StoreOrderRefundRequest();
        request.setAmount(amount);
        StoreOrder order = new StoreOrder();
        order.setOrderId(orderId);
        order.setMerId(productTypeMerchantId);
        // 获取支付渠道
        Integer type = orderUtils.getOrderPayType(productTypeMerchantId).getCode();
        if (type == 1) {
            order.setIsChannel(1);
            order.setPayPrice(request.getAmount());
            order.setRefundPrice(request.getAmount());
            return storeOrderRefundService.refund(request, order);
        } else {
            return adapayDegreePayOrderProcess.refund(request, order, null);
        }
    }

    @Override
    public Boolean updateReserveMoney(Integer merId, Boolean add, BigDecimal money) {
        SupplierInfo supplierInfo = this.getSupplierInfo(merId);
        Supplier one = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getId, supplierInfo.getSupplierId()).last("limit 1"));
        one.setReserveMoney(add ? one.getReserveMoney().add(money) : one.getReserveMoney().subtract(money));
        reserveMoneyDetailService.saveReserveMoneyDetail(merId, null, null, money, one.getReserveMoney(), add ? "增加储备金余额" : "减少储备金余额");
        return supplierService.updateById(one);
    }

    @Override
    public CommonPage<ReserveMoneyDetail> getDetailList(Integer merId, PageParamRequest pageParamRequest) {
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<ReserveMoneyDetail> reserveMoneyDetails = reserveMoneyDetailService.list(Wrappers.<ReserveMoneyDetail>lambdaQuery().eq(ReserveMoneyDetail::getMerId, merId).orderByDesc(ReserveMoneyDetail::getId));
        return CommonPage.restPage(reserveMoneyDetails);
    }

    @Override
    public CommonPage<ChannelMerchantPurchaseResponse> getPurchaseList(Integer merId, PageParamRequest request) {
        List<ChannelMerchantPurchaseResponse> responses = new ArrayList<>();
        Page<Object> page = PageHelper.startPage(request.getPage(), request.getLimit());
        List<ChannelMerchantPurchase> channelMerchantPurchases = channelMerchantPurchaseService.list(Wrappers.<ChannelMerchantPurchase>lambdaQuery().eq(ChannelMerchantPurchase::getMerId, merId).orderByDesc(ChannelMerchantPurchase::getId));
        if (CollectionUtils.isEmpty(channelMerchantPurchases)) {
            return CommonPage.restPage(responses);
        }
        for (ChannelMerchantPurchase channelMerchantPurchase : channelMerchantPurchases) {
            ChannelMerchantPurchaseResponse response = new ChannelMerchantPurchaseResponse();
            BeanUtils.copyProperties(channelMerchantPurchase, response);
            response.setProductType(RoleEnum.getEnumByCode(channelMerchantPurchase.getProductType()).getMsg());
            responses.add(response);
        }
        PageInfo<ChannelMerchantPurchaseResponse> channelMerchantPurchaseResponsePageInfo = CommonPage.copyPageInfo(page, responses);

        return CommonPage.restPage(channelMerchantPurchaseResponsePageInfo);
    }

    @Override
    public ChannelMerchantPurchaseResponse getPurchaseStatus(String orderId) {
        ChannelMerchantPurchaseResponse response = new ChannelMerchantPurchaseResponse();
        ChannelMerchantPurchase channelMerchantPurchase = channelMerchantPurchaseService.getOne(Wrappers.<ChannelMerchantPurchase>lambdaQuery().eq(ChannelMerchantPurchase::getOrderId, orderId).last("limit 1"));
        BeanUtils.copyProperties(channelMerchantPurchase, response);
        response.setProductType(RoleEnum.getEnumByCode(channelMerchantPurchase.getProductType()).getMsg());
        return response;
    }

    /**
     * 功能描述: 生成订购列表
     * @Param: [orderId, productType, merId]
     * @Return: void
     * @Author: wangzh
     * @Date: 2023/5/6 16:18
     */
    private void createPurchaseOrder(String orderId, Integer productType, Integer merId){
        ChannelMerchantPurchase channelMerchantPurchase = new ChannelMerchantPurchase();
        channelMerchantPurchase.setMerId(merId);
        channelMerchantPurchase.setOrderId(orderId);
        channelMerchantPurchase.setProductInfo("账号套餐");
        channelMerchantPurchase.setProductType(productType);
        channelMerchantPurchase.setNumber(1);
        channelMerchantPurchase.setPrice(RoleEnum.getEnumByCode(productType).getPrice());
        channelMerchantPurchase.setRetailPrice(RoleEnum.getEnumByCode(productType).getPrice());
        channelMerchantPurchase.setPayStatus(false);
        channelMerchantPurchaseService.save(channelMerchantPurchase);
    }
}
